#!/usr/bin/env python

__author__ = 'rx.wen218@gmail.com'

import xmlrpclib
import postconverter
import time
import logging
from datetime import datetime

class FakeUserAgentTransport(xmlrpclib.Transport):
    """
    fake windows live writer's user agent
    some blog providers (such as csdn) don't accept request from abritary UA
    """
    user_agent = "Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1; Windows Live Writer 1.0)"
    #user_agent = "Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.2.10) Gecko/20100914 Firefox/3.6.10

class FakeUserAgentSafeTransport(xmlrpclib.SafeTransport):
    """
    fake windows live writer's user agent
    some blog providers (such as csdn) don't accept request from abritary UA
    """
    user_agent = "Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1; Windows Live Writer 1.0)"
    #user_agent = "Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.2.10) Gecko/20100914 Firefox/3.6.10


class MetaWeblogProvider(object):

    def __init__(self, url, user_name, password, only_summary_in_recent_posts = False, use_datetime = True, post_converter = postconverter.MetaWeblogPostConverter(), policy = None):
        self.logger = logging.getLogger(__name__)
        tr = None
        if url.startswith("https"):
            tr = FakeUserAgentSafeTransport()
        else:
            tr = FakeUserAgentTransport()
        self.meta_weblog_client = xmlrpclib.ServerProxy(url, transport = tr, use_datetime=use_datetime)
        blog_info = self.meta_weblog_client.blogger.getUsersBlogs("0", user_name, password)
        self.user_name = user_name
        self.password = password
        self.blog_id = blog_info[0]['blogid']
        self.only_summary_in_recent_posts = only_summary_in_recent_posts
        self.post_converter = post_converter
        self.policy = policy
    
    def GetPosts(self, max_posts_num = 9999, start_date = datetime.min.replace(year=1900), end_date = datetime.max):
        metaweblog_posts = self.meta_weblog_client.metaWeblog.getRecentPosts(self.blog_id, self.user_name, self.password, max_posts_num)
        if self.only_summary_in_recent_posts: 
            posts = []
# the post struct returned in getRecentPosts method doesn't include full post information
# so we use getPost method for each post to get its full information
            for post in metaweblog_posts:
                if post['dateCreated'] < start_date or post['dateCreated'] > end_date:
                    continue
                full_post = self.meta_weblog_client.metaWeblog.getPost(post['postid'], self.user_name, self.password)
                if self.policy and self.policy.query_interval > 0:
                    time.sleep(self.policy.query_interval)
                new_post = self.post_converter.GetGenericPost(full_post)
                posts.append(new_post)
        else:
            posts = [self.post_converter.GetGenericPost(p) for p in metaweblog_posts if p['dateCreated'] >= start_date and p['dateCreated'] <= end_date]

        return posts

    def AddPost(self, post):
        new_post = self.post_converter.GetSpecificPost(post)
        self.meta_weblog_client.metaWeblog.newPost(self.blog_id, self.user_name, self.password, new_post, True)
        if self.policy and self.policy.update_interval > 0:
            time.sleep(self.policy.update_interval)

    def UpdatePost(self, post):
        post_to_update = self.post_converter.GetSpecificPost(post)
        self.meta_weblog_client.metaWeblog.editPost(str(post.postid), self.user_name, self.password, post_to_update, True)
        if self.policy and self.policy.update_interval > 0:
            time.sleep(self.policy.update_interval)

    def DeleteAllPosts(self):
        posts = self.GetPosts()
        for post in posts:
            print "about to delete " + post.postid + ' ' + post.title
            self.meta_weblog_client.blogger.deletePost("blogporter_application", post.postid, self.user_name, self.password, False)
            if self.policy and self.policy.update_interval > 0:
                time.sleep(self.policy.update_interval)

